package entities;

import java.io.Serializable;

import javax.persistence.*;

import ejb.dto.PackageDTO;

import java.util.ArrayList;
import java.util.List;


/**
 * The persistent class for the packages database table.
 * 
 */
@Entity
@Table(name="packages", uniqueConstraints={
		@UniqueConstraint(columnNames={"NAME", "PERIOD_ID"}),
		@UniqueConstraint(columnNames={"PERIOD_ID", "HOTEL_ID", "EXCURSION_ID"})
})
@NamedQueries({
	@NamedQuery(name="Package.findAll", query="SELECT p FROM Package p"),
	@NamedQuery(name="Package.findByName", query="SELECT p FROM Package p WHERE p.name LIKE :search"),
	@NamedQuery(name="Package.findById", query="SELECT p FROM Package p WHERE p.id = :id"),
	@NamedQuery(name="Package.findByPeriod", query="SELECT p FROM Package p WHERE p.period IN :pe"),
	@NamedQuery(name="Package.findByPeriodAndLocation", query="SELECT p FROM Package p WHERE p.period IN :pe AND p.location = :l"),
	@NamedQuery(name="Package.findByLocation", query="SELECT p FROM Package p WHERE p.location = :l"),
	@NamedQuery(name="Package.getSamples", query="SELECT p FROM Package p")
})
public class Package implements Serializable {
	private static final long serialVersionUID = 1L;

	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	private int id;

	@Lob
	private String description;

	@ManyToOne
	private Location location;
	
	@ManyToOne
	private Hotel hotel;
	
	@ManyToOne
	private Excursion excursion;

	private String name;

	/**
	 * bi-directional many-to-one association to Period
	 */
	@ManyToOne
	private Period period;

	/**
	 * bi-directional many-to-one association to Reservation
	 */
	@OneToMany(mappedBy="pack")
	private List<Reservation> reservations;
	
	/**
	 * bi-directional many-to-many association to Hotel
	 */
	@ManyToMany
	@JoinTable(
		name="PACKAGES_HOTELS"
		, joinColumns={
			@JoinColumn(name="PACKAGE_ID", referencedColumnName="ID")
			}
		, inverseJoinColumns={
			@JoinColumn(name="HOTEL_ID", referencedColumnName="ID")
			}
		)
	private List<Hotel> hotels;
	
	/**
	 * bi-directional many-to-many association to Excursion
	 */
		@ManyToMany
		@JoinTable(
			name="PACKAGES_EXCURSIONS"
			, joinColumns={
				@JoinColumn(name="PACKAGE_ID", referencedColumnName="ID")
				}
			, inverseJoinColumns={
				@JoinColumn(name="EXCURSION_ID", referencedColumnName="ID")
				}
			)
		private List<Excursion> excursions;
		
		/**
		 * bi-directional many-to-many association to Flight
		 */
		@ManyToMany
		@JoinTable(
			name="PACKAGES_FLIGHTS1"
			, joinColumns={
				@JoinColumn(name="PACKAGE_ID", referencedColumnName="ID")
				}
			, inverseJoinColumns={
				@JoinColumn(name="FLIGHT_ID", referencedColumnName="ID")
				}
			)
		private List<Flight> flights1;

		/**
		 * bi-directional many-to-many association to Flight
		 */
		@ManyToMany
		@JoinTable(
			name="PACKAGES_FLIGHTS2"
			, joinColumns={
				@JoinColumn(name="PACKAGE_ID", referencedColumnName="ID")
				}
			, inverseJoinColumns={
				@JoinColumn(name="FLIGHT_ID", referencedColumnName="ID")
				}
			)
		private List<Flight> flights2;
	
	

	//CONSTRUCTORS
	public Package() {
	}
	
	public Package(PackageDTO pack, Location location, Period period, Hotel hotel, Excursion excursion, List<Flight> flightList1, List<Flight> flightList2, List<Hotel> hotelList, List<Excursion> excursionList){
		this.id = pack.getId();
		this.description = pack.getDescription();
		this.name = pack.getName();
		this.location = location;
		this.period = period;
		this.excursion = excursion;
		this.hotel = hotel;
		this.hotels = hotelList;
		this.excursions = excursionList;
		this.flights1 = flightList1;
		this.flights2 = flightList2;
	}

	
	
	//GETTER AND SETTER
	
	public Hotel getHotel() {
		return hotel;
	}

	public void setHotel(Hotel hotel) {
		this.hotel = hotel;
	}

	public Excursion getExcursion() {
		return excursion;
	}

	public void setExcursion(Excursion excursion) {
		this.excursion = excursion;
	}
	
	public int getId() {
		return this.id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getDescription() {
		return this.description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public Location getLocation() {
		return this.location;
	}

	public void setLocation(Location location) {
		this.location = location;
	}

	public String getName() {
		return this.name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Period getPeriod() {
		return this.period;
	}

	public void setPeriod(Period period) {
		this.period = period;
	}

	public List<Reservation> getReservations() {
		return this.reservations;
	}

	public void setReservations(List<Reservation> reservations) {
		this.reservations = reservations;
	}
	
	public List<Hotel> getHotels() {
		return hotels;
	}

	public void setHotels(List<Hotel> hotels) {
		this.hotels = hotels;
	}

	public List<Excursion> getExcursions() {
		return excursions;
	}

	public void setExcursions(List<Excursion> excursions) {
		this.excursions = excursions;
	}

	public List<Flight> getFlights1() {
		return flights1;
	}

	public void setFlights1(List<Flight> flights1) {
		this.flights1 = flights1;
	}
	
	public List<Flight> getFlights2() {
		return flights2;
	}

	public void setFlights2(List<Flight> flights2) {
		this.flights2 = flights2;
	}
	
	public List<Hotel> getAllHotels() {
		List<Hotel> list = new ArrayList<Hotel>(getHotels());
		list.add(getHotel());
		return list;
	}
	
	public List<Excursion> getAllExcursions() {
		List<Excursion> list = new ArrayList<Excursion>(getExcursions());
		list.add(getExcursion());
		return list;
	}
	
	//METHODS
	
	/**
	 * add Reservation to list
	 * @param reservation
	 * @return list of Reservation
	 */
	public Reservation addReservation(Reservation reservation) {
		getReservations().add(reservation);
		reservation.setPackage(this);

		return reservation;
	}

	/**
	 * remove Reservation from list
	 * @param reservation
	 * @return list of Reservation
	 */
	public Reservation removeReservation(Reservation reservation) {
		getReservations().remove(reservation);
		reservation.setPackage(null);

		return reservation;
	}
	
}